Skip to content

feat: UI/UX polish — adopt @freecodecamp/ui, onboarding, class page (#609) - #616

Open
NewtonLC wants to merge 38 commits into
freeCodeCamp:mainfrom
NewtonLC:feat/609-ui-ux-polish
Open

NewtonLC wants to merge 38 commits into
freeCodeCamp:mainfrom
NewtonLC:feat/609-ui-ux-polish

Conversation

@NewtonLC

Copy link
Copy Markdown
Contributor

Checklist:

  • I have read freeCodeCamp's contribution guidelines.
  • My pull request has a descriptive title (not a vague title like Update index.md)
  • My pull request targets the main branch of freeCodeCamp.
  • I have tested these changes either locally on my machine, or GitHub Codespaces.

Addresses #609.

This PR delivers the UI/UX work from #609 in one diff, so the whole redesign can be reviewed against the old design at once. It supersedes #604, #610, #612, and #607, which are merged into this branch (their history is preserved).

Headline change: Classroom now uses @freecodecamp/ui

Instead of hand-copying freeCodeCamp styles, Classroom depends on freeCodeCamp's own component library (@freecodecamp/ui@6.1.0, pinned, the same package freeCodeCamp's learn site uses) and its design tokens. Where the library has no equivalent, components follow freeCodeCamp's site code (header, progress bar, heatmap, .btn-cta, typography).

Area Now uses
Buttons Button; yellow .btn-cta (ported from fCC's global.css) for each page's main action
Create/Edit Class, Delete confirmation Modal (danger variant for delete)
Forms FormGroup, ControlLabel, FormControl, HelpBlock + a FormSelect helper
Class card Panel + Dropdown/MenuItem Actions menu
Messages Alert, Callout; toasts themed like Alert
Collapsible sections HeadlessDisclosure
Tables Table + shared TablePagination
Landing page guides Tabs
Navbar Rebuilt after fCC's header (Menu dropdown on phones)

#609 items

  1. Teacher onboarding (item 1): the home page shows the signed-in role and role-aware getting-started guides (For teachers / For students tabs; students see only the student guide; admins get a pointer to the admin dashboard).
  2. Create/Edit Class modals (item 2, from feat: Redesign Create and Edit Class Modals #612): shared ClassModal on the library Modal; the certification dropdown is inline, searchable, and fCC-themed; Edit pre-fills values and only sends changed fields. The "no certifications" restriction (fix(modal): disable button and update styles based on selection #552/fix: require certification before creating class #611) is intentionally not included; see the update on Feature: UI/UX Polishing for Classroom #609.
  3. Class cards (item 3, from feat: Class Card UI/UX updates #610): 100/500 character limits with counters, 2/4-line clamping, a keyboard-accessible certification popover, and an Actions menu.
  4. Class page (item 4, with feat: Improve Teacher Feedback for Fetch Failures and Empty Classrooms #607): header with class name, description, certification tags, student count, created date, and a copyable invite link; fCC-styled empty and fetch-error states.
  5. fCC design alignment (item 5, from refactor: Synchronize FreeCodeCamp CSS Styling #604): library tokens and base styles app-wide, fCC typography rules, consistent page layouts and titles, restyled navbar, dashboard, student details (heatmap, per-certification progress with a scrollable block list), and admin pages.

Bugs fixed along the way

  • Renaming a class never saved (the modal sent classroomName, editclass read className).
  • Editing with no changes always reported "Class updated"; it now says "No changes were made." without a request.
  • A class could be created without certifications but never edited to have none (editclass turned [] into "no change").
  • A failed delete (400/500) was reported as success and removed the card.
  • Every toast rendered twice (multiple ToastContainers); there is now one, in _app.js.
  • The users table showed "1–0 of 0" and a "0" page size when empty.
  • Students with no completions showed a 1969 "last completion" date.
  • The heatmap's "contributions" count actually counted active days; it's now labelled "active days".
  • Duplicate ids (menu-button on every card, progress on every row).
  • The Role label on the edit-user form pointed at the Name field.
  • feat: Improve Teacher Feedback for Fetch Failures and Empty Classrooms #607's new fetchStudentData return shape broke the student details page (mock mode); callers are updated, and fCC API failures now show the error state instead of crashing.

Things reviewers should know

  • Node 24 is now required (engines.node >= 24). @freecodecamp/ui declares node >= 24 and this repo's .npmrc sets engine-strict=true. CI already runs Node 24.
  • Library workarounds (upstream issues for freeCodeCamp/ui to be filed separately):
    • Modal panel has a fixed width and overflows phones → capped with max-width: 100% in globals.css.
    • FormControl ignores its own classes when given className → layout classes go on wrappers.
    • base.css makes every <table> inline-block, so Table's w-full doesn't stretch → table.w-full { display: table } plus scroll wrappers.
  • Navbar API changed: pages render <Navbar /> and pass page-specific links via extraLinks; the navbar owns the role-based links. "Menu" is renamed "Home"; the logo links to / (same as fix(navbar): point home button to root route #613).
  • Not touched: the v1 dashboard (pages/dashboard/[id].js, slated for deletion) beyond a one-line fix to keep it working.

Testing

  • npm test: 149 tests pass (new tests cover the edit/delete flows, the editclass API, navbar roles, pagination, onboarding, the class page, disclosures, activity/progress).
  • Manually tested each page at desktop and phone widths as teacher, admin, student, and signed out.

Screenshots

🤖 Generated with Claude Code

NewtonLC and others added 30 commits April 28, 2026 14:36
This stops a 'Conflicting Peer Dependency' error from occurring when you run npm install
while react is currently below 18.3.1
Created a navButton class for navigation button instances
Added responsive design to make web app more mobile-friendly
freeCodeCamp#606)

- fetchStudentData now returns { error, data } instead of a bare array,
  distinguishing FETCH_FAILED, NETWORK_ERROR, and MISSING_URL cases
- [id].js selects fccUserIds from Prisma, handles structured fetch result,
  and passes fetchError, fccUserIds, and joinLink as props
- DashTabs shows an empty-classroom state with the join link and copy
  button when no students are enrolled, and a user-facing error message
  for runtime fetch failures
Updated fetchStudentData to change the return shape from empty arrays to specific errors
Updated dashboard/v2/[id].js to take that return shape and render the UI accordingly
Teachers can now hover over it to easily see which certifications are part of their class
on the Classes page. Previously, they needed to press the Edit Class button and
scroll through the certifications list.
Users can only write class titles of up to 100 characters and descriptions of up to 500 characters.
The Class card truncates after 2 lines of the class title and 4 lines of the description.
Refactor the code in modal.js and ClassInviteTable.js into a shared component in ClassModal.js
Create the FloatingMultiSelect.js modal to make the Select Certification dropdown appear on top of the backdrop
Switch from overlaying JSX in place with ReactDOM.createPortal() to make the modal appear fully over the page
Updated test files and snapshots, added temporary comments to explain the changes.
# Conflicts:
#	__tests__/components/__snapshots__/modal.test.jsx.snap
# Conflicts:
#	__tests__/components/__snapshots__/modal.test.jsx.snap
#	components/ClassInviteTable.js
#	components/modal.js
- Add @freecodecamp/ui@6.1.0 (pinned) and load its base.css before globals.css
- Set the light-palette class on <body>
- Mirror the library's Tailwind config (semantic colors, palette, fonts,
  font sizes); legacy fcc-* aliases now point at the same CSS variables
- Disable Classroom's own preflight since base.css already ships it
- Load Lato 300/400/700/italic weights
- Require Node >=24 (the package's engine requirement; CI already uses 24)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Add Link and ButtonLink helpers mirroring freeCodeCamp's client helpers
  (internal links use Next's router, external links open in a new tab)
- Replace hand-styled buttons across Classroom with @freecodecamp/ui Button
- Port fCC's .btn-cta for main actions and style the navbar auth button
  like fCC's header Sign in (fits the 38px bar)
- Port fCC's heading, paragraph, and .big-heading rules into globals.css
- Rebuild the error and join pages with one consistent layout and page titles
- Turn non-heading <h1>s (modal labels, card description, details rows) into text
- Remove button CSS made obsolete by the library

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Use Modal (Headless UI Dialog) with Header/Body/Footer: backdrop and Escape
  close, focus trap, dialog semantics, close button
- Use FormGroup/ControlLabel/FormControl/HelpBlock for the fields; stacked
  CTA + Cancel footer buttons
- Render the certification MultiSelect inline and theme it with fCC tokens;
  remove FloatingMultiSelect (the fCC panel doesn't clip overflow)
- Close the modal on Escape from the closed certification dropdown
- Cap the library's fixed-width modal panel at the viewport width on phones
- Stub ResizeObserver in modal tests, as freeCodeCamp's own tests do

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Add FormSelect helper: a native select styled like the library's FormControl
- Rebuild the update-user form with FormGroup/ControlLabel/FormControl, add a
  page title and blank-field hint, and fix the Role label pointing at Name
- Use FormControl/ControlLabel/FormSelect for the teacher invite email and
  filters; add an accessible label to the invite email input
- Keep layout classes on wrappers since FormControl drops its own classes
  when given a className

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Card uses Panel/Panel.Heading/Panel.Title/Panel.Body; drop the full-card
  dark hover inversion and the "Classroom:" title prefix
- Replace the hand-rolled "..." menu with Dropdown/Dropdown.Toggle/MenuItem
  (keyboard support, outside-click/Escape handling, menu semantics)
- Rename the "Invite" action to "Copy invite link"
- Make the certification popover keyboard-reachable and restyle it with fCC tokens
- Give each card's menu a unique id; stack title above controls on phones

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lout

- Confirm class deletion in a danger-variant Modal instead of confirm()
- Report class card results with toasts instead of alert(); add an Info toast
- Use Alert/Callout on the teacher invitation page instead of custom boxes
- Mount a single ToastContainer in _app (each container rendered every toast)

Fixes:
- A failed delete (400/500) was reported as success and removed the card
- Edit sent every field, so "no changes" was never detected; it now sends only
  changed fields and skips the request when nothing changed
- editclass read the name from `className`, so renames never saved; it now
  reads `classroomName` like the create API
- editclass turned an empty certification list into "no change", so a class
  could be created without certifications but never edited to have none

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tions

- Admin Teacher Invitations and User Database sections
- Student details "View details" toggles
- Render the toggle as the library Button so the open state uses its
  aria-expanded styling; add tests for the details disclosure

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Class dashboard, admin users, and teacher invitations tables render through
  the library Table (striped), matching freeCodeCamp's table styling
- Remove inline and CSS-module table styles (including the monospace font)
- Port fCC's td/th text rule into globals.css

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 38px bar with centered logo (linking to /) and fCC nav-button styling:
  bordered buttons that turn white on hover/focus
- Collapse links into a Menu dropdown (library Dropdown) below 768px and
  shrink the logo so everything fits on phones
- Navbar owns its role-based links (Classes / Dashboard -> /admin / Home)
  instead of parsing page JSX; pages pass extra links via extraLinks
- Rename the "Menu" home link to "Home" and "<" to "Back to class"
- Remove unused navbar/Login/Invite CSS modules and .navButton

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
NewtonLC and others added 8 commits September 26, 2026 19:44
- Use react-toastify's light theme with the Alert's per-variant text,
  background and border colors, square corners and Lato
- Icon, countdown bar and close button follow each toast's text color
- Load the toast stylesheet before globals.css so the theme overrides it

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Add TablePagination (FormSelect + library Buttons with accessible names)
  and use it in the users and teacher invitations tables
- Fix the users table showing "1-0 of 0" and a "0" page size when empty,
  and reset to page 1 when the page size changes
- Remove the duplicated pagination code and CSS

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Activity shows a colored dot plus an Active/Inactive label (active = at
  least one completion in the past week), using fCC palette colors
- Show "No completions yet" instead of a 1969 date for students with none
- Replace the per-row <meter> (duplicate id) with a ProgressBar that mirrors
  freeCodeCamp's progress bar and exposes progressbar semantics

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Page title as a big-heading with the student email and class name
- Heatmap in freeCodeCamp's light profile-heatmap style (Lato, fCC colors),
  labelled "active days" (what it counts) and opened on the latest weeks
- One Panel per certification with a completed/total ProgressBar in the
  heading and a striped block Table that scrolls after ~10 rows with a
  pinned header
- Restore table layout for library Tables (base.css makes them
  inline-block) and wrap the dashboard table for horizontal scrolling
- Remove DetailsCSS.module.css and the Roboto Mono font

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Show the signed-in role (or a Sign in CTA) on the home page
- Teacher and student getting-started guides in library Tabs; students see
  only the student guide, admins also get a pointer to the admin dashboard
- Real page title instead of "Create Next App"

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… feat/609-ui-ux-polish

Conflict resolution:
- fetchStudentData.js: keep main's fetchClassroomStudentData (fCC API) and
  freeCodeCamp#607's { error, data } version of the mock fetchStudentData
- dashboard/v2/[id].js: keep main's FCC_API_URL / mock switch, and turn fCC
  API failures into freeCodeCamp#607's fetchError instead of crashing; keep freeCodeCamp#607's empty
  and error states with the new Navbar (restyled in the next commit)
- Update getIndividualStudentData and the v1 dashboard for the new
  fetchStudentData return shape (freeCodeCamp#607 didn't cover these callers)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- ClassroomHeader: class name, description, student count and creation
  date, certification tags, and a copyable invite link
- Load class details and readable certification names on the class page
- Restyle freeCodeCamp#607's empty and fetch-error states with Callout and Alert
- Real page title instead of "Create Next App"

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Classes page: "Your classes" title, usage hint, and a no-classes note
- Admin page: "Admin dashboard" big-heading and fCC section styling
- Real tab titles on the classes, admin, and edit-user pages
- Delete styles/Home.module.css (create-next-app boilerplate)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​freecodecamp/​ui@​6.1.0861008296100

View full report

@NewtonLC NewtonLC self-assigned this Sep 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants